package com.cly.config;

import com.cly.base.contants.UserConstants;
import com.cly.properties.SwaggerProperties;
import io.swagger.v3.oas.models.Components;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import io.swagger.v3.oas.models.security.SecurityRequirement;
import io.swagger.v3.oas.models.security.SecurityScheme;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springdoc.core.customizers.GlobalOpenApiCustomizer;
import org.springdoc.core.models.GroupedOpenApi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * Swagger全局配置
 * <p>
 * 用于配置Swagger API自动生成工具的配置
 *
 * @author by 春风能解释
 * <p>
 * 2023/7/14
 */
@Configuration
@Slf4j
// http://localhost:8080/swagger-ui/index.html
public class SwaggerConfiguration {

    /**
     * swagger配置键
     */
    @Resource
    private SwaggerProperties swaggerProperties;

    // /**
    //  * API接口核心配置
    //  *
    //  * @return 接口对象
    //  */
    // @Bean
    // public Docket createRestApi() {
    //     //创建响应体
    //     List<Response> responses = new ArrayList<>();
    //     //遍历自定义异常
    //     for (RequestException request : RequestException.values()) {
    //         responses.add(new ResponseBuilder()
    //                 .code(request.getStatus().toString())//状态码
    //                 .description(request.getMessage())//消息
    //                 .build());
    //     }
    //     //分离配置
    //     Docket groupName = new Docket(DocumentationType.OAS_30)
    //             .enable(swaggerProperties.getEnabled())//是否启用
    //             .groupName(swaggerProperties.getGroupName());
    //     //遍历请求方法
    //     for (HttpMethod method : HttpMethod.values()) {
    //         groupName.globalResponses(method, responses);
    //     }
    //     //拼接最后的配置
    //     Docket docket = groupName
    //             .apiInfo(apiInfo())
    //             .select()
    //             .apis(RequestHandlerSelectors.any())
    //             .paths(PathSelectors.any())
    //             //排除默认错误界面
    //             .paths(PathSelectors.regex("(?!/error.*).*"))
    //             .build();
    //     log.info("swagger已成功加载!");
    //     return docket;
    // }

    /**
     * 分组配置
     *
     * @return 分组对象
     */
    @Bean
    public GroupedOpenApi groupOpenApi() {
        return GroupedOpenApi.builder()
                .group(swaggerProperties.getGroupName())
                .pathsToMatch("/**")
                .build();
    }

    /**
     * 全局认证配置
     *
     * @return 配置
     */
    @Bean
    public GlobalOpenApiCustomizer globalOpenApiCustomizer() {
        return openApi -> {
            // 全局添加鉴权参数
            if (openApi.getPaths().isEmpty()) {
                return;
            }
            openApi.getPaths().forEach((s, pathItem) -> {
                // 接口添加鉴权参数
                pathItem.readOperations()
                        .forEach(operation ->
                                operation.addSecurityItem(new SecurityRequirement().addList(UserConstants.AUTHORIZATION))
                        );
            });
        };
    }

    /**
     * 摘要信息
     *
     * @return 初始化API
     */
    @Bean
    public OpenAPI apiInfo() {
        OpenAPI info = new OpenAPI()
                // 配置全局鉴权参数-Authorize
                .components(new Components()
                        .addSecuritySchemes(UserConstants.AUTHORIZATION,
                                new SecurityScheme()
                                        .name(UserConstants.AUTHORIZATION)
                                        .type(SecurityScheme.Type.APIKEY)
                                        .in(SecurityScheme.In.HEADER)
                        )
                )
                .info(new Info()
                        .title(swaggerProperties.getTitle())
                        .description(swaggerProperties.getDescription())
                        .version(swaggerProperties.getVersion())
                        .contact(new Contact()
                                .name(swaggerProperties.getAuthor())
                                .email(swaggerProperties.getEmail())
                                .url(swaggerProperties.getUrl())));
        log.info("swagger开发者信息已成功注入!");
        return info;
    }
}
